home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / AXHEARD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-23  |  6.5 KB  |  306 lines

  1. /* AX25 link callsign monitoring. Also contains beginnings of
  2.  * an automatic link quality monitoring scheme (incomplete)
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include "global.h"
  7. #include "ctype.h"
  8. #include "mbuf.h"
  9. #include "iface.h"
  10. #include "pool.h"
  11.  
  12. #if !defined(_lint)
  13. static char rcsid[] OPTIONAL = "$Id: axheard.c,v 1.13 1996/12/23 20:37:36 root Exp root $";
  14. #endif
  15.  
  16. #define iscallsign(c) ((isupper(c)) || (isdigit(c)) || (c ==' '))
  17. int axheard_filter_flag = AXHEARD_PASS;
  18.  
  19. static struct lq *al_create (struct iface * ifp, char *addr);
  20. static struct ld *ad_create (struct iface * ifp, const char *addr);
  21. struct lq *Lq;
  22. struct ld *Ld;
  23.  
  24. extern int Maxax25heard;
  25.  
  26. #ifdef POOLED
  27. struct mempool lq_pool = {NULLPOOLBLK, NULLPOOLBLK, 0, sizeof (struct lq), 50};
  28. struct mempool ld_pool = {NULLPOOLBLK, NULLPOOLBLK, 0, sizeof (struct ld), 50};
  29. #endif
  30.  
  31.  
  32. #if 0
  33. /* Send link quality reports to interface */
  34. void
  35. genrpt (ifp)
  36. struct iface *ifp;
  37. {
  38. struct mbuf *bp;
  39. register char *cp;
  40. int i;
  41. struct lq *lp;
  42. int maxentries, nentries;
  43.  
  44.     maxentries = (Paclen - LQHDR) / LQENTRY;
  45.     if ((bp = alloc_mbuf (Paclen)) == NULLBUF)
  46.         return;
  47.     cp = bp->data;
  48.     nentries = 0;
  49.  
  50.     /* Build and emit header */
  51.     cp = putlqhdr (cp, LINKVERS, Ip_addr);
  52.  
  53.     /* First entry is for ourselves. Since we're examining the Axsent
  54.      * variable before we've sent this frame, add one to it so it'll
  55.      * match the receiver's count after he gets this frame.
  56.      */
  57.     cp = putlqentry (cp, ifp->hwaddr, Axsent + 1);
  58.     nentries++;
  59.  
  60.     /* Now add entries from table */
  61.     for (lp = lq; lp != NULLLQ; lp = lp->next) {
  62.         cp = putlqentry (cp, &lp->addr, lp->currxcnt);
  63.         if (++nentries >= MAXENTRIES) {
  64.             /* Flush */
  65.             bp->cnt = nentries * LQENTRY + LQHDR;
  66.             ax_output (ifp, Ax25multi[0], ifp->hwaddr, PID_LQ, bp);
  67.             if ((bp = alloc_mbuf (Paclen)) == NULLBUF)
  68.                 return;
  69.             cp = bp->data;
  70.         }
  71.     }
  72.     if (nentries > 0) {
  73.         bp->cnt = nentries * LQENTRY + LQHDR;
  74.         ax_output (ifp, Ax25multi[0], ifp->hwaddr, LQPID, bp);
  75.     } else
  76.         free_p (bp);
  77. }
  78.  
  79.  
  80. /* Pull the header off a link quality packet */
  81. void
  82. getlqhdr (hp, bpp)
  83. struct lqhdr *hp;
  84. struct mbuf **bpp;
  85. {
  86.     hp->version = pull16 (bpp);
  87.     hp->ip_addr = pull32 (bpp);
  88. }
  89.  
  90.  
  91. /* Put a header on a link quality packet.
  92.  * Return pointer to buffer immediately following header
  93.  */
  94. char *
  95. putlqhdr (cp, version, ip_addr)
  96. register char *cp;
  97. int16 version;
  98. uint32 ip_addr;
  99. {
  100.     cp = put16 (cp, version);
  101.     return put32 (cp, ip_addr);
  102. }
  103.  
  104.  
  105. /* Pull an entry off a link quality packet */
  106. void
  107. getlqentry (ep, bpp)
  108. struct lqentry *ep;
  109. struct mbuf **bpp;
  110. {
  111.     pullup (bpp, ep->addr, AXALEN);
  112.     ep->count = pull32 (bpp);
  113. }
  114.  
  115.  
  116. /* Put an entry on a link quality packet
  117.  * Return pointer to buffer immediately following header
  118.  */
  119. char *
  120. putlqentry (cp, addr, count)
  121. char *cp;
  122. char *addr;
  123. int32 count;
  124. {
  125.     memcpy (cp, addr, AXALEN);
  126.     cp += AXALEN;
  127.     return put32 (cp, count);
  128. }
  129. #endif
  130.  
  131.  
  132. /* Log the source address of an incoming packet */
  133. void
  134. logsrc (ifp, addr)
  135. struct iface *ifp;
  136. char *addr;
  137. {
  138. register struct lq *lp;
  139. register unsigned char c;
  140. register int i = 0;
  141.  
  142.     if (axheard_filter_flag & AXHEARD_NOSRC || !(ifp->flags & LOG_AXHEARD))
  143.         return;
  144.  
  145.     while (i < AXALEN - 1) {
  146.         c = uchar(*(addr + i));
  147.         c >>= 1;
  148.         if (!iscallsign (c))
  149.             return;
  150.         i++;
  151.     }
  152.  
  153.     if ((lp = al_lookup (ifp, addr, 1)) == NULLLQ)
  154.         if ((lp = al_create (ifp, addr)) == NULLLQ)
  155.             return;
  156.     lp->currxcnt++;
  157.     lp->time = secclock ();
  158. }
  159.  
  160.  
  161. /* Log the destination address of an incoming packet */
  162. void
  163. logdest (ifp, addr)
  164. struct iface *ifp;
  165. const char *addr;
  166. {
  167. register struct ld *lp;
  168. register unsigned char c;
  169. register int i = 0;
  170.  
  171.     if (axheard_filter_flag & AXHEARD_NODST || !(ifp->flags & LOG_AXHEARD))
  172.         return;
  173.  
  174.     while (i < AXALEN - 1) {
  175.         c = uchar(*(addr + i));
  176.         c >>= 1;
  177.         if (!iscallsign (c))
  178.             return;
  179.         i++;
  180.     }
  181.  
  182.     if ((lp = ad_lookup (ifp, addr, 1)) == NULLLD)
  183.         if ((lp = ad_create (ifp, addr)) == NULLLD)
  184.             return;
  185.     lp->currxcnt++;
  186.     lp->time = secclock ();
  187. }
  188.  
  189.  
  190. /* Look up an entry in the source data base */
  191. struct lq *
  192. al_lookup (ifp, addr, sort)
  193. struct iface *ifp;
  194. char *addr;
  195. int sort;
  196. {
  197. register struct lq *lp;
  198. struct lq *lplast = NULLLQ;
  199.  
  200.     for (lp = Lq; lp != NULLLQ; lplast = lp, lp = lp->next) {
  201.         if (addreq (lp->addr, addr) && (lp->iface == ifp)) {
  202.             if (sort && lplast != NULLLQ) {
  203.                 /* Move entry to top of list */
  204.                 lplast->next = lp->next;
  205.                 lp->next = Lq;
  206.                 Lq = lp;
  207.             }
  208.             return lp;
  209.         }
  210.     }
  211.     return NULLLQ;
  212. }
  213.  
  214.  
  215. /* Create a new entry in the source database */
  216. /* If there are too many entries, override the oldest one - WG7J */
  217. static struct lq *
  218. al_create (ifp, addr)
  219. struct iface *ifp;
  220. char *addr;
  221. {
  222. static int numdb = 0;
  223. register struct lq *lp;
  224. struct lq *lplast = NULLLQ;
  225.  
  226.     if (Maxax25heard && numdb == Maxax25heard) {
  227.         /* find and use last one in list */
  228.         for (lp = Lq; lp->next != NULLLQ; lplast = lp, lp = lp->next)
  229.             ;
  230.         /* delete entry from end */
  231.         if (lplast)
  232.             lplast->next = NULLLQ;
  233.     } else {        /* create a new entry */
  234.         numdb++;
  235. #ifdef POOLED
  236.         lp = (struct lq *) pool_alloc (&lq_pool);
  237. #else
  238.         lp = (struct lq *) callocw (1, sizeof (struct lq));
  239. #endif
  240.     }
  241.     memcpy (lp->addr, addr, AXALEN);
  242.     lp->iface = ifp;
  243.     lp->next = Lq;
  244.     Lq = lp;
  245.  
  246.     return lp;
  247. }
  248.  
  249.  
  250. /* Look up an entry in the destination database */
  251. struct ld *
  252. ad_lookup (ifp, addr, sort)
  253. struct iface *ifp;
  254. const char *addr;
  255. int sort;
  256. {
  257. register struct ld *lp;
  258. struct ld *lplast = NULLLD;
  259.  
  260.     for (lp = Ld; lp != NULLLD; lplast = lp, lp = lp->next) {
  261.         if ((lp->iface == ifp) && addreq (lp->addr, addr)) {
  262.             if (sort && lplast != NULLLD) {
  263.                 /* Move entry to top of list */
  264.                 lplast->next = lp->next;
  265.                 lp->next = Ld;
  266.                 Ld = lp;
  267.             }
  268.             return lp;
  269.         }
  270.     }
  271.     return NULLLD;
  272. }
  273.  
  274.  
  275. /* Create a new entry in the destination database */
  276. static struct ld *
  277. ad_create (ifp, addr)
  278. struct iface *ifp;
  279. const char *addr;
  280. {
  281. static int numdb = 0;
  282. register struct ld *lp;
  283. struct ld *lplast = NULLLD;
  284.  
  285.     if (Maxax25heard && numdb == Maxax25heard) {    /* find and use last one in list */
  286.         for (lp = Ld; lp->next != NULLLD; lplast = lp, lp = lp->next)
  287.             ;
  288.         /* delete entry from end */
  289.         if (lplast)
  290.             lplast->next = NULLLD;
  291.     } else {        /* create a new entry */
  292.         numdb++;
  293. #ifdef POOLED
  294.         lp = (struct ld *) pool_alloc (&ld_pool);
  295. #else
  296.         lp = (struct ld *) callocw (1, sizeof (struct ld));
  297. #endif
  298.     }
  299.     memcpy (lp->addr, addr, AXALEN);
  300.     lp->iface = ifp;
  301.     lp->next = Ld;
  302.     Ld = lp;
  303.  
  304.     return lp;
  305. }
  306.